/********************************
 * ETK - Easy ToolKit
 * Copyright (C) 2007-2008 Ekinoks
 * All rights reserved.
 *
 *    This file is part of ETK.
 *
 *    Foobar is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    Foobar is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Foobar; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ***********************************************************************************/

#ifndef __ETK_WIDGET_H__
#define __ETK_WIDGET_H__
#include <iostream>
#include <set>

#include <boost/bind.hpp>
#include <boost/function.hpp>

#include "../StateModel/StateModel.h"
#include "../CallBack/CallBack.h" /// friend
#include "../Event/EventButton/EventButton.h"

#include "../Shutter/ShutterScroll/ShutterScrollModel.h"
#include "../Shutter/ShutterKey/ShutterKeyModel.h"

namespace etk
{
    class WidgetContainer;
    class Event;
    class RWidget;


    /** Classe de base pour les widget
    *
    */
    class Widget
    {
        private :
            std::set<CallBack*> listCallBack;

            RWidget *rWidget;

            /** MyContainer est responsable des communications avec le WidgetContainer qui nous contient
            *
            */
            class MyContainer
            {
                public :
                    MyContainer(Widget *me, WidgetContainer * value);
                    ~MyContainer();
                private :
                    Widget *me_;
                    WidgetContainer * value_;
            } myContainer;

        public :

            /** Constructeur
            *
            */
            Widget(RWidget *rWidget, WidgetContainer * container);


            // //////////////////////////////////////////////
            // //////////////// EVENTS /////////////////////
            // ////////////////////////////////////////////

            template <class F>
            CallBack * toDeleted(F f);

            template <class F>
            CallBack * toButtonEvent(F f, ShutterButtonModel shutter=ShutterButtonModel::ANY, StateModel stateModel=StateModel::ANY);   // ok

            template <class F>
            CallBack * toScrolled(F f, ShutterScrollModel shutter=ShutterScrollModel::ANY, StateModel stateModel=StateModel::ANY);      // ok

            template <class F>
            CallBack * toMotionNotify(F f, StateModel stateModel=StateModel::ANY);

            template <class F>
            CallBack * toKeyPressed(F f, ShutterKeyModel shutterKeyModel=ShutterKeyModel::ANY, StateModel stateModel=StateModel::ANY);     // ok

            template <class F>
            CallBack * toKeyReleased(F f, ShutterKeyModel shutterKeyModel=ShutterKeyModel::ANY, StateModel stateModel=StateModel::ANY);     // ok

            template <class F>
            CallBack * toFocusIn(F f);

            template <class F>
            CallBack * toFocusOut(F f);

            // ...

            // /////////////// FIN EVENTS //////////////////


            /// Rendre le widget visible
            void show() const;

            /// Rendre le widget invisible
            void hide() const;

            virtual ~Widget();

            RWidget* getRWidget() const;    // TODO : faire en sorte que seulement ToolKit et ses désandants puissent utiliser cette méthode

            void destroy();
         private :
            // ////////////////////////// ////////////////////////
            // //////// GESTION SEMI-PERSONEL DES EVENTS ///////
            // ////////////////////////////////////////////////
            friend class CallBackI;

            /// Indiquer au widget que le CallBack 'callback' fait référance sur lui.
            CallBack* add_call_back(CallBack *callback); // interdire au public

            /// Indiquer au widget que le CallBack 'callback' a été suprimé.
            void remove_call_back(CallBack *callback); // interdire au public
            // ///// FIN GESTION SEMI-PERSONEL DES EVENTS //////////////////////
    };


}


#include "Widget.tpp"


#endif /* #ifndef __ETK_WIDGET_H__ */




